package attr

import (
	"context"
	tools "mall/common/utils"
	"mall/services/product/rpc/internal/domain/bo"
	"mall/services/product/rpc/internal/domain/do"
	"mall/services/product/rpc/internal/mapper"
	"mall/services/product/rpc/internal/mapper/entity"
	"mall/services/product/rpc/internal/svc"
	"mall/services/product/rpc/pb"

	"github.com/zeromicro/go-zero/core/logx"
)

type PageListLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewAttrPageListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PageListLogic {
	return &PageListLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *PageListLogic) AttrPageList(in *pb.AttrPageListDTO) (*pb.AttrPageListVO, error) {
	// 1.select count
	attrMapper, selectCountCtx, err := l.selectCount(in)
	if err != nil {
		return nil, err
	}
	// 1.1 if select count eq 0,return obj
	if selectCountCtx <= 0 {
		return &pb.AttrPageListVO{PageSize: in.PageSize, CurrentPage: in.PageNum}, nil
	}
	// 2.select List
	selectList, categoryMap, err := l.selectList(in, attrMapper)
	if err != nil {
		return nil, err
	}
	// 3.package obj
	resp := l.packageObj(in, selectCountCtx, selectList, categoryMap)
	return resp, nil
}

func (l *PageListLogic) packageObj(in *pb.AttrPageListDTO, selectCountCtx int64,
	selectList []entity.AttrEntity, categoryMap map[int64]do.AttrCategoryDO) *pb.AttrPageListVO {

	resp := new(pb.AttrPageListVO)
	pageUtil := tools.NewPageUtil[entity.AttrEntity](in.PageNum, in.PageNum, int32(selectCountCtx), selectList)
	resp.TotalPage = pageUtil.TotalPage
	resp.HasNextPage = pageUtil.HasNextPage
	resp.CurrentPage = pageUtil.CurrentPage
	resp.TotalCount = pageUtil.TotalCount
	resp.Prev = pageUtil.Prev
	resp.PageSize = in.PageSize
	resp.Next = pageUtil.Next
	records := pageUtil.Records
	var recordArr []*pb.AttrListInfoVO
	for _, v := range records {
		p := new(pb.AttrListInfoVO)
		p.AttrId = v.AttrId
		p.CreateTime = v.CreateTime.Format("2006-01-02 15:04:05")
		p.UpdateTime = v.UpdateTime.Format("2006-01-02 15:04:05")
		p.ShopId = v.ShopId
		p.Name = v.Name
		p.Desc = v.Desc
		p.SearchType = int32(v.SearchType)
		p.AttrType = int32(v.AttrType)
		categoryDO := categoryMap[v.AttrId]
		if categoryDO.AttrId > 0 {
			p.CategoryId = categoryDO.CategoryId
			p.CategoryName = categoryDO.Name
		}
		recordArr = append(recordArr, p)
	}
	resp.Records = recordArr
	return resp
}

func (l *PageListLogic) selectList(in *pb.AttrPageListDTO, attrMapper *mapper.AttrMapper) (
	[]entity.AttrEntity, map[int64]do.AttrCategoryDO, error) {

	attrBO := bo.AttrBO{NameAllLike: in.Name}
	attrBO.ShopId = in.ShopId
	pageSize := in.PageSize
	pageNum := in.PageNum
	startPageIndex := 0
	if pageNum > 1 {
		startPageIndex = int((pageNum - 1) * pageSize)
	}
	attrBO.PageSize = int(in.PageSize)
	attrBO.StartIndex = startPageIndex
	selectListCtx, err := attrMapper.SelectListCtx(l.svcCtx.DBEngin, attrBO)
	if err != nil {
		return nil, nil, err
	}
	// query attr category info
	var attrIdArr []int64
	for _, v := range selectListCtx {
		attrIdArr = append(attrIdArr, v.AttrId)
	}
	categoryMapper := mapper.NewAttrCategoryMapper(l.ctx)
	attrCategoryDOList, err := categoryMapper.SelectCategoryByAttrIdArr(l.svcCtx.DBEngin, attrIdArr)
	if err != nil {
		return nil, nil, err
	}
	categoryMap := make(map[int64]do.AttrCategoryDO)
	for _, v := range attrCategoryDOList {
		categoryMap[v.AttrId] = v
	}
	return selectListCtx, categoryMap, nil
}

func (l *PageListLogic) selectCount(in *pb.AttrPageListDTO) (*mapper.AttrMapper, int64, error) {
	attrMapper := mapper.NewAttrMapper(l.ctx)
	attrBO := bo.AttrBO{NameAllLike: in.Name}
	attrBO.ShopId = in.ShopId
	selectCountCtx, err := attrMapper.SelectCountCtx(l.svcCtx.DBEngin, attrBO)
	if err != nil {
		return nil, -1, err
	}
	return attrMapper, selectCountCtx, nil
}
